# $Id: ip4.sh.in 771 2008-10-15 01:36:24Z enki $
#
# ip4.sh: IPv4 address functions
# ---------------------------------------------------------------------------
test $lib_net_ip4_sh || {

# directories
# -------------------------------------------------------------------------
: ${prefix:="@prefix@"}
: ${sbindir:="${exec_prefix}/sbin"}
: ${libdir:="${exec_prefix}/lib"}
: ${shlibdir:="${libdir}/sh"}

# ip4_mask <address> <mask>
#
# Masks the address using the mask to get the network address. 
# -------------------------------------------------------------------------
ip4_mask()
{
  local addr mask

  addr=`ip4_to_dec "$1"`
  mask=`ip4_to_dec "$2"`

  ip4_from_dec $((addr & mask))
}

# ip4_broadcast <address> <mask>
#
# Logically ORs the address using the inverse of the netmask to get the
# broadcast address.
# -------------------------------------------------------------------------
ip4_broadcast()
{
  local addr broadcast

  addr=`ip4_to_dec "$1"`
  mask=`ip4_to_dec "$2"`

  ip4_from_dec $((addr | ~mask))
}

# ip4_from_dec <number>
#
# Converts a 32-bit number into IPv4 address notation.
# -------------------------------------------------------------------------
ip4_from_dec()
{
  local a b c d

  a=$(($1 >> 24 & 0xff))
  b=$(($1 >> 16 & 0xff))
  c=$(($1 >> 8 & 0xff))
  d=$(($1 & 0xff))

  echo "$a.$b.$c.$d"
}

# ip4_to_hex <ip-address>
# 
# Converts an IPv4 address from dotted notation to a hexadecimal number.
# -------------------------------------------------------------------------
ip4_to_hex()
{
  local IFS=.

  printf "%02x%02x%02x%02x\n" $1
}

# ip4_to_bits <ip-address>
#
# Converts an IPv4 address to a 2's-complement.
# -------------------------------------------------------------------------
ip4_to_bits()
{
  hex_to_bin "`ip4_to_hex $1`"
}

# ip4_to_dec <ip-address>
#
# Converts an IPv4 address from dotted notation to decimal.
# -------------------------------------------------------------------------
ip4_to_dec()
{
  hex_to_dec "`ip4_to_hex $1`"
}

# ip4_cidr <ip-address> <network-mask>
#
# Converts (an address and) a network mask from IPv4 notation to a CIDR netmask number.
# -------------------------------------------------------------------------
ip4_cidr()
{
  local addr= ipmask binmask
  
  if test -n "$2"; then
    addr=$1
    shift
  fi
  
  ipmask=${1:-"0.0.0.0"}
  binmask=`ip4_to_bits "$ipmask"`

  echo ${addr:+"`ip4_mask "$addr" "$ipmask"`/"}`str_length "${binmask%%0*}"`
}

# ip4_valid
#
# is it a valid ip address?
# -------------------------------------------------------------------------
ip4_valid()
{
  local IFS=.

  set -- $1

  # must be 4 bytes
  test "$#" = 4 || return 1

  # range-check each byte
  while [ "$#" -gt 0 ]; do
    if [ "$1" -gt 255 -o "$1" -lt 0 ]; then
      return 1
    fi
    shift
  done

  return 0
}

# --- eof ---------------------------------------------------------------------
lib_net_ip4_sh=:;}
